package cn.sumpu.app.guoguojie.biz.impl;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import cn.sumpu.app.guoguojie.biz.IdentifierBiz;
import cn.sumpu.app.guoguojie.biz.LuckyBiz;
import cn.sumpu.app.guoguojie.dao.LuckyDao;
import cn.sumpu.app.guoguojie.domain.LuckRank;
import cn.sumpu.app.guoguojie.domain.LuckTime;
import cn.sumpu.app.guoguojie.exception.AppBusinessException;
import cn.sumpu.app.guoguojie.util.Common;
import cn.sumpu.app.guoguojie.util.PageModel;

public class LuckyBizImpl implements LuckyBiz {
    private LuckyDao luckyDao;

    public void setLuckyDao(LuckyDao luckyDao) {
        this.luckyDao = luckyDao;
    }

    @Autowired
    private IdentifierBiz idBiz;

    @Override
    public void saveLuckTime(LuckTime luckTime) throws AppBusinessException {
        if (!Common.empty(luckTime)) {
            if (!Common.empty(luckTime.getLtime())) {
                luckTime.setLtime(luckTime.getLtime() + " 13:30:00");
            }
            if (Common.empty(luckTime.getIdentifier())) {
                luckTime.setStatus("ready");
                luckTime.setIdentifier(idBiz.generateId("luck_time"));
                luckyDao.insertLuckTime(luckTime);
            } else {
                luckyDao.updateLuckTime(luckTime);
            }
        }
    }

    @Override
    public void deleteLuckTime(String id) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("identifier", id);
        luckyDao.deleteLuckTime(map);

    }

    @Override
    public LuckTime getLuckTimeById(String id) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("identifier", id);
        List<LuckTime> list = luckyDao.getLuckTime(map);
        if (list != null && list.size() == 1) {
            return list.get(0);
        }
        return null;
    }

    @Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
    @Override
    public PageModel getLuckTime(Integer page, Integer pageSize, String title, String status) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        page = page == null ? 1 : page;
        int size = pageSize == null ? 20 : pageSize;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        if (!Common.empty(title)) {
            map.put("title", "%" + title + "%");
        }
        if (!Common.empty(status)) {
            map.put("status", status);
        }
        int count = luckyDao.getLuckTimeCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        List<LuckTime> list = luckyDao.getLuckTime(map);
        pm.setList(list);
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    @Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
    @Override
    public PageModel getLuckRank(Integer page, Integer pageSize, String luckid) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        page = page == null ? 1 : page;
        int size = pageSize == null ? 20 : pageSize;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        map.put("luckid", luckid);
        int count = luckyDao.getLuckRankCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        List<LuckRank> list = luckyDao.getLuckRank(map);
        pm.setList(list);
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    @Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
    @Override
    public PageModel getHistoryLuckRank(Integer page, Integer pageSize, String luckid) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        page = page == null ? 1 : page;
        int size = pageSize == null ? 20 : pageSize;
        map.put("startId", (page - 1) * size);
        map.put("pageSize", size);
        map.put("luckid", luckid);
        map.put("notrepeat", "notrepeat");
        int count = luckyDao.getLuckRankCount(map);
        PageModel pm = new PageModel();
        pm.setCurrentPage(page);
        List<LuckRank> list = luckyDao.getLuckRank(map);
        pm.setList(list);
        pm.setPageSize(size);
        pm.setTotalRecord(count);
        pm.setTotalPage((count + size - 1) / size);
        return pm;
    }

    //定时
    public void timeCheckLuckTime() {
        String nowDate = Common.getFormatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
        try {
            startLuckTime(nowDate);//自动打开离现在最近的一期
            finishLuckTime(nowDate);//结束开奖时间在当前的一期
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startLuckTime(String nowDate) throws AppBusinessException {
        Date now = new Date();
        String d = "";
        String week = getWeekOfDate(now);
        LuckTime luckTime = new LuckTime();
        luckTime.setIdentifier(idBiz.generateId("luck_time"));
        luckTime.setStatus("start");
        luckTime.setTitle("现金5元");
        luckTime.setDescription("只记录最好成绩，分享越多机会越多每周1、3、5开奖");
        luckTime.setFinanum(10);
        if (week.equals("星期一") || week.equals("星期三")) {
            d = Common.getFormatDate(getDateAfter(new Date(), 2), "yyyy-MM-dd");
        } else if (week.equals("星期五")) {
            d = Common.getFormatDate(getDateAfter(new Date(), 3), "yyyy-MM-dd");
        }
        luckTime.setLtime(d + " 13:30:00");
        luckyDao.insertLuckTime(luckTime);
        System.out.println("打开了幸运排名期刊" + luckTime.getIdentifier() + "时间为:" + nowDate);
    }

    private void finishLuckTime(String nowDate) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", "start");
        map.put("endTime", nowDate);
        List<LuckTime> list = luckyDao.getLuckTime(map);
        if (list != null && list.size() == 1) {
            LuckTime luckTime = list.get(0);
            luckTime.setStatus("end");
            luckyDao.updateLuckTime(luckTime);
            System.out.println("结束了幸运排名期刊" + luckTime.getIdentifier() + "时间为:" + nowDate);
        }
    }

    @Transactional(rollbackForClassName = { "cn.sumpu.app.guoguojie.exception.AppBusinessException" }, timeout = 10)
    @Override
    public LuckRank getRankNum(String memberId) throws AppBusinessException {
        LuckTime startLuckTime = getStartLuckTime();
        String luckId = startLuckTime.getIdentifier();
        if (Common.empty(startLuckTime)) {
            return null;
        }
        Integer rankNum = null;
        boolean numEable = false;
        do {
            rankNum = Common.rand(99999);
            numEable = checkRankNum(luckId, rankNum);
        } while (!numEable);

        LuckRank luckRank = getMemberRank(luckId, memberId);
        if (Common.empty(luckRank)) {
            //如果是第一次排名则产生一条排名记录
            luckRank = new LuckRank();
            luckRank.setLuckid(luckId);
            luckRank.setRanknum(rankNum);
            luckRank.setMember(memberId);
            luckRank.setLuckdate(Common.getFormatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
            luckyDao.insertLuckRank(luckRank);
        } else {
            //如果有排名记录并且产生的随机数字小于历史幸运数则更新为最好成绩
            if (luckRank.getRanknum() > rankNum) {
                luckRank.setRanknum(rankNum);
                luckyDao.updateLuckRank(luckRank);
            }

        }
        Integer rank = getMemberRank(luckId, luckRank.getRanknum());
        Integer finanum = startLuckTime.getFinanum();
        luckRank.setRank(rank);
        luckRank.setLuckTimeObj(startLuckTime);
        luckRank.setCurrentRankNum(rankNum);
        int d = rank - finanum;
        if (d < 0) {
            luckRank.setSortResult("暂列第" + rank + "，已经入围");
        } else {
            luckRank.setSortResult("暂列第" + rank + "，离入围还差" + (rank - finanum) + "位");
        }

        return luckRank;
    }

    @Override
    public Integer getMemberRank(String luckTimeId, Integer rankNum) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("luckid", luckTimeId);
        map.put("mynum", rankNum);
        Integer count = luckyDao.getLuckRankCount(map);
        if (count != null) {
            return count + 1;
        }
        return null;
    }

    @Override
    public LuckRank getMemberRank(String luckTimeId, String memberId) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("luckid", luckTimeId);
        map.put("member", memberId);
        LuckTime luckTime = getLuckTimeById(luckTimeId);
        if (Common.empty(luckTime)) {
            return null;
        }
        List<LuckRank> list = luckyDao.getLuckRank(map);
        if (list != null && list.size() == 1) {
            LuckRank luckRank = list.get(0);
            Integer rank = getMemberRank(luckTimeId, luckRank.getRanknum());
            luckRank.setRank(rank);
            int d = rank - luckTime.getFinanum();
            if (d < 0) {
                luckRank.setSortResult("暂列第" + rank + "，已经入围");
            } else {
                luckRank.setSortResult("暂列第" + rank + "，离入围还差" + (rank - luckTime.getFinanum()) + "位");
            }
            return luckRank;
        }
        return null;
    }

    public boolean checkRankNum(String luckTimeId, Integer rankNum) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("luckid", luckTimeId);
        map.put("ranknum", rankNum);
        int count = luckyDao.getLuckRankCount(map);
        if (count > 0) {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkLuckTime(String luckTimeId) throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("identifier", "luckTimeId");
        map.put("status", "start");
        map.put("currentTime", Common.getFormatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
        int luckTimeCount = luckyDao.getLuckTimeCount(map);
        if (luckTimeCount == 1) {
            return true;
        }
        return false;
    }

    @Override
    public LuckTime getStartLuckTime() throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("currentTime", Common.getFormatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
        map.put("status", "start");
        List<LuckTime> list = luckyDao.getLuckTime(map);
        if (list != null && list.size() == 1) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public LuckTime getLastLuckTime() throws AppBusinessException {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("lastTime", "lastTime");
        map.put("status", "end");
        List<LuckTime> list = luckyDao.getLuckTime(map);
        if (list != null && list.size() == 1) {
            return list.get(0);
        }
        return null;
    }

    /** 
     * 得到当前时间星期几
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /** 
     * 得到几天后的时间 
     */

    public static Date getDateAfter(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }

    public static void main(String[] args) {
        System.out.println(Common.getFormatDate(getDateAfter(new Date(), 2), "yyyy-MM-dd"));
    }
}
